package com.yupi.springbootinit.bizmq;

import com.rabbitmq.client.Channel;
import com.yupi.springbootinit.common.ErrorCode;
import com.yupi.springbootinit.exception.ThrowUtils;
import com.yupi.springbootinit.manager.AIManager;
import com.yupi.springbootinit.model.entity.Chart;
import com.yupi.springbootinit.service.ChartService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

@Component
@Slf4j
public class BiMessageConsumer {

    @Resource
    ChartService chartService;

    @Resource
    AIManager aiManager;

    @Resource
    private ThreadPoolExecutor threadPoolExecutor;

    private static final String systemContent =
            "你是一个数据分析师和前端开发专家";


    @SneakyThrows // 注解简化异常处理
    @RabbitListener(queues = {BiMqConstant.BI_QUEUE_NAME}, ackMode = "MANUAL")  // 指定监听队列，并手动消息确认
    public void receiveMessage(String message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) {
        log.info("receiveMessage message={}", message);

        ThrowUtils.throwIf(message == null,ErrorCode.SYSTEM_ERROR,"消息为空");
        Long chartId = Long.valueOf(message);

        //1.从数据库里获取要拼接成AI输入的图表信息
        Chart chart = chartService.getById(chartId);
        ThrowUtils.throwIf(chart == null,ErrorCode.SYSTEM_ERROR,"消费图表id无法得到图表信息");
        String goal = chart.getGoal();
        String charType = chart.getCharType();
        String charData = chart.getCharData();
        // todo 如果想用上那个独立出来的图表原始数据表，可以根据id查询得到表，写一个方法实现将表转成字符串
        //2.拼接用户输入
        StringBuilder userInput = new StringBuilder();
        userInput.append("分析需求：").append("{").append(goal).append("}").append("\n");
        //2.2以下是AI问答业务  2.3 拼接分析目标和图表类型
        userInput.append("图表格式：").append("{").append(charType).append("}").append("\n");
        userInput.append("原始数据：").append("{").append(charData).append("}").append("\n");
        userInput.append("请根据输入内容，按照以下指定格式生成内容（此外不要输出任何多余的开头、结尾）\n" +
                "=====\n" +
                "{按照分析需求进行数据可视化，生成前端 Echarts V5 的 option 配置对象JSON代码，代码内不要有注释，所有代码都应放在option配置对象里，不要使用Markdown格式输出代码，直接以文本格式输出代码}\n" +
                "=====\n" +
                "{明确的数据分析结论、越详细越好，不要生成多余的注释}" +
                "在你给出前端代码和数据分析结论之间都先打印一行=====");

        //0.改变图表生成状态为running
        Chart updateChart = new Chart();
        updateChart.setId(chartId);
        updateChart.setStatus("running");
        boolean b = chartService.updateById(updateChart);
        ThrowUtils.throwIf(!b, ErrorCode.SYSTEM_ERROR, "图表正在生成状态保存失败");

        //1.调用AI
        String AIResult = aiManager.AIChat(systemContent, userInput.toString());
        //2.生成返回结果
        String genChart;
        String genResult;
        String[] split = AIResult.split("=====");
        if (split.length < 3) {
            log.error("AI生成错误");
            //除去option =
            String searchString0 = "option = ";
            int index0 = AIResult.indexOf(searchString0);
            if (index0 != -1) {
                AIResult = AIResult.substring(index0 + searchString0.length());
            }
            String[] split2 = AIResult.split("```");
            if (split2.length >= 2) {
                String searchString = "javascript";
                int index = split2[1].indexOf(searchString);
                if (index != -1) {
                    split2[1] = split2[1].substring(index + searchString.length());
                }
                genResult = split2.length == 2 ? null : split2[2];
                genChart = split2[1];
            } else {
                genResult = AIResult;
                genChart = AIResult;
            }
        } else {
            genChart = split[1];
            genResult = split[2];
            //2.4对genChart进行处理
            //除去option =
            String searchString = "option = ";
            int index = genChart.indexOf(searchString);
            if (index != -1) {
                genChart = genChart.substring(index + searchString.length());
            }
            //除去 ```javascript```
            String[] splitWithoutPoint = genChart.split("```");
            if (splitWithoutPoint.length >= 2) {
                searchString = "javascript";
                index = splitWithoutPoint[1].indexOf(searchString);
                if (index != -1) {
                    genChart = splitWithoutPoint[1].substring(index + searchString.length());
                }
            }
        }
        // 3.将AI生成结果写入数据库
        Chart resultChart = new Chart();
        resultChart.setId(chartId);
        resultChart.setStatus("succeed");
        resultChart.setGenChart(genChart);
        resultChart.setGenResult(genResult);
        boolean update = chartService.updateById(resultChart);
        ThrowUtils.throwIf(!update, ErrorCode.SYSTEM_ERROR, "图表生成成功状态保存失败");


        channel.basicAck(deliveryTag, false);  //告诉要确认的消息，确认后从队列中删去
    }
}
